<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        *{margin:0;padding: 0}
        .box{
            width: 100px;
            height: 100px;
            background: red;
            position: absolute;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="box" v-drag ></div>
    </div>
    <!-- <div data-id="0"  class="box"></div> -->
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    //Vue.directive 包含Vue可用的指令表,
    /**指令钩子函数会被传入以下参数：
    el：指令所绑定的元素，可以用来直接操作 DOM。
    binding：一个对象，包含以下 property：
        name：指令名，不包括 v- 前缀。
        value：指令的绑定值，例如：v-my-directive="1 + 1" 中，绑定值为 2。
        oldValue：指令绑定的前一个值，仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
        expression：字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中，表达式为 "1 + 1"。
        arg：传给指令的参数，可选。例如 v-my-directive:foo 中，参数为 "foo"。
        modifiers：一个包含修饰符的对象。例如：v-my-directive.foo.bar 中，修饰符对象为 { foo: true, bar: true }。
    vnode：Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
    oldVnode：上一个虚拟节点，仅在 update 和 componentUpdated 钩子中可用
     */
    Vue.directive("drag",{
        bind(el) {
            let isDragStart=false;
            let disX=0, disY=0;
            let el_width,el_height;
            el.addEventListener("mousedown", e =>{
                disX = e.offsetX;
                disY = e.offsetY;
                el_width=e.target.offsetWidth;
                el_height=e.target.offsetHeight;
                isDragStart=true; 
                e.preventDefault();

            });
            el.addEventListener("mousemove",e=>{
                if(isDragStart){
                    var l = e.clientX - disX;
                    var t = e.clientY - disY;
                
                    // 限制可拖动窗口在视口范围内
                    if(l < 0 )l=0;
                    if(t < 0 )t=0;
                    if(l + el_width > window.innerWidth ) l = window.innerWidth - el_width;
                    if(t + el_height> window.innerHeight ) t = window.innerHeight - el_height;
                    el.style.left = l + 'px';
                    el.style.top = t + 'px';  
                }
            })
            el.addEventListener("mouseup",e=>{
                isDragStart=false;
            });
        }
    });


    new Vue({
        el:"#app",
        data:{
            flag:true,
            // msg:"123"
        }
    })
</script>